﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Linq;

using System.Data.SqlClient;

namespace SC.CodeBuilder
{
    public partial class MainForm : Form
    {
        //关键字数组
        private string[] keys = new string[] { 
            "using",  
            "namespace",
            "private", 
            "public", 
            "class", 
            "interface", 
            "static",
            "readonly",
            "sealed",
            "#region",
            "#endregion",
            "new", 
            "string",
            "int", 
            "float", 
            "double",
            "void",
            "object", 
            "value",
            "return",
            "set", 
            "get",
            "try",
            "catch",
            "null",
            "if",
            "List"
        
        };
        //类名或接口名数组
        private string[] classes = new string[] { "Serializable", "IComparable", "IComparer", "" };
        //特殊符号数组
        private char[] marks = new char[] { ' ', '\n', ';', ':', '{', '}', '[', ']', '/', '<', '>', '(', ')' };
        //窗体构造函数
        public MainForm()
        {
            InitializeComponent();
        }
        //窗体加载
        private void MainForm_Load(object sender, EventArgs e)
        {
            chbIsUseWindwos.Checked = !chbIsUseWindwos.Checked;
            chbIsUseWindwos.Checked = !chbIsUseWindwos.Checked;
        }
        //是否使用windows登陆
        private void chbIsUseWindwos_CheckedChanged(object sender, EventArgs e)
        {
            label11.Visible = !chbIsUseWindwos.Checked;
            label12.Visible = !chbIsUseWindwos.Checked;
            txtUserName.Visible = !chbIsUseWindwos.Checked;
            txtPwd.Visible = !chbIsUseWindwos.Checked;

            if (chbIsUseWindwos.Checked)
            {
                btnOpenSql.Location = new System.Drawing.Point(311, 5);
            }
            else
            {
                btnOpenSql.Location = new System.Drawing.Point(620, 5);
            }
            label10.Location = new Point(btnOpenSql.Location.X + btnOpenSql.Width + 5, 10);
            cbbDbName.Location = new Point(label10.Location.X + label10.Width, 6);
        }
        //连接数据库，并且添加数据表列表
        private void btnOpenSql_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtServerIp.Text))
            {
                MessageBox.Show("请填写服务器地址");
                return;
            }
            if (!chbIsUseWindwos.Checked && string.IsNullOrWhiteSpace(txtUserName.Text) || !chbIsUseWindwos.Checked && string.IsNullOrWhiteSpace(txtPwd.Text))
            {
                MessageBox.Show("请填写数据库连接账号或密码");
            }
            if (!SetConnStr("master")) { MessageBox.Show("连接字符不能为空"); return; };
            string[] alllis;
            btnOpenSql.Enabled = false;
            try
            {
                alllis = Builder.GetDataBases().ToArray();
                btnOpenSql.Enabled = true;
            }
            catch
            {
                MessageBox.Show("数据库连接错误");
                btnOpenSql.Enabled = true;
                return;
            }
            cbbDbName.Items.Clear();
            cbbDbName.Items.AddRange(alllis);
            cbbDbName.SelectedIndex = 32;
            label10.Visible = true;
            cbbDbName.Visible = true;
            cbCheckAll.Visible = true;
        }
        //选中新数据库之后
        private void cbbDbName_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!SetConnStr(cbbDbName.Text.Trim())) { MessageBox.Show("数据库连接配置错误"); }
            string[] alllis;
            try
            {
                alllis = Builder.GetTables(txtUserName.Text.Trim()).ToArray();
            }
            catch { MessageBox.Show("打开数据库失败"); return; }
            cklbTables.Items.Clear();
            cklbTables.Items.AddRange(alllis);
            //cklbTables.SetItemChecked(9, true);
            //cklbTables.SetItemChecked(11, true);
            //cklbTables.SetItemChecked(12, true);
            //cklbTables.SetItemChecked(13, true);
            //cklbTables.SetItemChecked(14, true);
            //cklbTables.SetItemChecked(15, true);
            //cklbTables.SetItemChecked(16, true);
            //cklbTables.SetItemChecked(18, true);
            //cklbTables.SetItemChecked(22, true);
            cklbTables.SetItemChecked(26, true);
        }
        //打开文件夹
        private void btnSelectFolder_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog fb = new FolderBrowserDialog())
            {
                fb.ShowNewFolderButton = true;
                if (!string.IsNullOrWhiteSpace(txtOutFolder.Text))
                {
                    fb.SelectedPath = txtOutFolder.Text;
                }
                if (fb.ShowDialog() == DialogResult.OK)
                {
                    txtOutFolder.Text = fb.SelectedPath;
                }
            }
        }
        //开始生成
        private void btnBeginMarke_Click(object sender, EventArgs e)
        {
            rt.Clear();
            rtInfo.Clear();
            if (cklbTables.CheckedItems.Count < 1) { MessageBox.Show("你没选择表", "提示"); return; }

            foreach (string st in cklbTables.CheckedItems)
            {
                int shors = 0;
                if (cbModel.Checked)
                {
                    if (chkSort.Checked && !chkComparer.Checked)
                    {
                        if (radList.Checked) shors = 1;
                        else shors = 2;
                    }
                    if (!chkSort.Checked && chkComparer.Checked) shors = 3;
                    else if (!chkSort.Checked && !chkComparer.Checked) shors = 6;
                    else if (radList.Checked && chkComparer.Checked) shors = 4;
                    else if (radObject.Checked && chkComparer.Checked) shors = 5;

                }
                if (rabOutToWindow.Checked)
                {
                    #region 生成到代码窗口
                    using (Builder du = new Builder(
                        st,
                        txtNameSpace.Text,
                        txtSqlHelperName.Text,
                        shors,
                        cbAdd.Checked,
                        cbUpdate.Checked,
                        cbDelete.Checked,
                        cbGetModel.Checked,
                        cbGetList.Checked,
                        cbExists.Checked,
                        cbGetMaxID.Checked,
                        cbGetRecordCount.Checked,
                        cbRow2Model.Checked,
                        cbIDAL.Checked
                        ))
                    {
                        if (cbModel.Checked)
                        {
                            rt.Text += du.BuildeModelSB();
                            rtInfo.Text += st + "\tModel生成成功\t" + DateTime.Now + "\r\n";
                        }
                        if (cbDAL.Checked)
                        {
                            rt.Text += du.BuildeDALSB();
                            rtInfo.Text += st + "\tDAL生成成功\t" + DateTime.Now + "\r\n";
                        }
                        if (cbBLL.Checked)
                        {
                            rt.Text += du.BuildeBLLSB();
                            rtInfo.Text += st + "\tBLL生成成功\t" + DateTime.Now + "\r\n";
                        }
                        if (cbIDAL.Checked)
                        {
                            rt.Text += du.BuildeIDALSB();
                            rtInfo.Text += st + "\tIDAL生成成功\t" + DateTime.Now + "\r\n";
                            rt.Text += du.BuildeDALFactorySB();
                            rtInfo.Text += st + "\tDALFactory生成成功\t" + DateTime.Now + "\r\n";
                        }
                    }
                    tabControl1.SelectedIndex = 1;
                    #endregion
                }
                else
                {
                    #region 生成到文件
                    if (cbIsUseNameSpaseToFileName.Checked && string.IsNullOrWhiteSpace(txtNameSpace.Text)) { MessageBox.Show("已选择使用命名空间做文件夹前缀，但未填写命名空间", "提示"); return; }
                    if (string.IsNullOrWhiteSpace(txtOutFolder.Text)) { MessageBox.Show("没有选择输出目录", "提示"); return; }
                    using (Builder du = new Builder(
                        st,
                        txtNameSpace.Text,
                        txtSqlHelperName.Text,
                        shors,
                        cbAdd.Checked,
                        cbUpdate.Checked,
                        cbDelete.Checked,
                        cbGetModel.Checked,
                        cbGetList.Checked,
                        cbExists.Checked,
                        cbGetMaxID.Checked,
                        cbGetRecordCount.Checked,
                        cbRow2Model.Checked,
                        cbIDAL.Checked))
                    {
                        if (cbModel.Checked)
                        {
                            WriteFile(txtOutFolder.Text + "\\" + (cbIsUseNameSpaseToFileName.Checked ? (txtNameSpace.Text + ".") : "") + "Model\\" + Builder.UpperLetter(st) + ".cs",
                                du.BuildeModelSB());
                            rtInfo.Text += st + "\tModel生成成功\t" + DateTime.Now + "\r\n";
                        }
                        if (cbDAL.Checked)
                        {
                            WriteFile(txtOutFolder.Text + "\\" + (cbIsUseNameSpaseToFileName.Checked ? (txtNameSpace.Text + ".") : "") + "DAL\\" + Builder.UpperLetter(st) + ".cs",
                               du.BuildeDALSB());
                            rtInfo.Text += st + "\tDAL生成成功\t" + DateTime.Now + "\r\n";
                        }

                        if (cbBLL.Checked)
                        {
                            WriteFile(txtOutFolder.Text + "\\" + (cbIsUseNameSpaseToFileName.Checked ? (txtNameSpace.Text + ".") : "") + "BLL\\" + Builder.UpperLetter(st) + ".cs",
                               du.BuildeBLLSB());
                            rtInfo.Text += st + "\tBLL生成成功\t" + DateTime.Now + "\r\n";
                        }
                        if (cbIDAL.Checked)
                        {
                            WriteFile(txtOutFolder.Text + "\\" + (cbIsUseNameSpaseToFileName.Checked ? (txtNameSpace.Text + ".") : "") + "IDAL\\I" + Builder.UpperLetter(st) + ".cs",
                               du.BuildeIDALSB());
                            rtInfo.Text += st + "\tIDAL生成成功\t" + DateTime.Now + "\r\n";
                            WriteFile(txtOutFolder.Text + "\\" + (cbIsUseNameSpaseToFileName.Checked ? (txtNameSpace.Text + ".") : "") + "BLL\\DALFactory.cs",
                               du.BuildeDALFactorySB());
                            rtInfo.Text += st + "\tDALFactory生成成功\t" + DateTime.Now + "\r\n";
                        }
                    }
                    #endregion
                }
            }
            //rt.Text += "全部代码生成完毕";
            if (cbCodeColor.Checked)
            {
                setKeyColor();
                setColor();
            }
        }
        //Model排序方式选择
        private void chkSort_CheckedChanged(object sender, EventArgs e)
        {
            radList.Enabled = radObject.Enabled = chkSort.Checked;
        }
        //输出到代码窗口还是输出到文本
        private void OutPutToFilesOrWindow(object sender, EventArgs e)
        {
            rabOutToWindow.Checked = !rabOutToFiles.Checked;
            cbCodeColor.Visible = rabOutToWindow.Checked;
            label5.Visible = txtOutFolder.Visible = btnSelectFolder.Visible = cbIsUseNameSpaseToFileName.Visible = rabOutToFiles.Checked;
        }
        //窗口关闭时保存各个控件状态
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Properties.Settings.Default.Save();
        }
        //全选按钮
        private void cbCheckAll_CheckedChanged(object sender, EventArgs e)
        {
            for (int j = 0; j < cklbTables.Items.Count; j++)
                cklbTables.SetItemChecked(j, cbCheckAll.Checked);
        }
        #region 设置连接字符串 - bool SetConnStr(string _name)
        /// <summary>
        /// 设置连接字符串
        /// </summary>
        /// <param name="_name">要连接的数据库名字</param>
        /// <returns></returns>
        bool SetConnStr(string _name)
        {
            SqlConnectionStringBuilder ssb = new SqlConnectionStringBuilder();
            ssb.DataSource = txtServerIp.Text.Trim();
            ssb.InitialCatalog = _name;// txtDbName.Text.Trim();
            ssb.IntegratedSecurity = chbIsUseWindwos.Checked;
            ssb.UserID = txtUserName.Text.Trim();
            ssb.Password = txtPwd.Text;
            string sql = ssb.ToString();
            if (string.IsNullOrWhiteSpace(sql)) { return false; }
            else { SqlHelper.connstr = sql; return true; }
        }
        #endregion
        #region 写入文件 - void WriteFile(string path, StringBuilder sb)
        /// <summary>
        /// 写入文件
        /// </summary>
        /// <param name="path">要写入的文件的路径</param>
        /// <param name="sb">要写入的数据</param>
        static void WriteFile(string path, StringBuilder sb)
        {
            if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); }
            using (FileStream fs = new FileStream(path, FileMode.Create))
            {
                using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
                {
                    sw.Write(sb);
                    sw.Flush();
                }
            }
        }
        #endregion
        #region 更改关键字的颜色 - void setKeyColor()
        /// <summary>
        /// 更改关键字和注释的颜色
        /// </summary>
        private void setKeyColor()
        {
            //更改关键字的颜色
            int start = 0;
            int end = 0;
            string text = rt.Text;
            List<char> temp = new List<char>();
            bool isMark = false;
            foreach (char x in text.ToCharArray())
            {
                foreach (char mark in marks)
                {
                    if (x == mark)
                    {
                        isMark = true;
                        break;
                    }
                }
                if (isMark)
                {
                    StringBuilder word = new StringBuilder();
                    foreach (char y in temp)
                        word.Append(y.ToString());
                    foreach (string z in keys)
                    {
                        if (word.ToString() == z)
                        {
                            rt.Select(start, word.Length);
                            rt.SelectionColor = Color.Blue;
                            break;
                        }
                    }
                    foreach (string z in classes)
                    {
                        if (word.ToString() == z)
                        {
                            rt.Select(start, word.Length);
                            rt.SelectionColor = Color.CadetBlue;
                            break;
                        }
                    }
                    start = ++end;
                    temp.Clear();
                    isMark = false;
                }
                else
                {
                    temp.Add(x);
                    end++;
                }
            }
        }
        /// <summary>
        /// //更改注释的颜色
        /// </summary>
        private void setColor()
        {
            //更改注释的颜色
            string text = rt.Text;
            int count = 0;
            while (true)
            {
                int _start = text.IndexOf("///", count) + 3;
                if (_start == 2)
                    break;
                int _end = text.IndexOf('\n', _start);
                count = _end;
                string str = text.Substring(_start, _end - _start);
                str = str.Trim();
                if (str[0] == '<' && str[str.Length - 1] == '>')
                {
                    rt.Select(_start - 3, (_end - _start) + 3);
                    rt.SelectionColor = Color.Gray;
                }
                else
                {
                    rt.Select(_start - 3, 3);
                    rt.SelectionColor = Color.Gray;
                    rt.Select(_start, (_end - _start) + 3);
                    rt.SelectionColor = Color.Green;
                }
            }
        }
        #endregion
    }
}
